/*
 * TrackPoint.java
 *
 * Created on 20 juin 2006, 19:49
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package courselog.gpsutils;

/**
 * A location point obtained from the log of a track.
 * Carries additional fields that MeasuredPoint s does not have.
 * @author rigal
 */
public class TrackPoint extends MeasuredPoint {
    
    /**
     * Average speed (km/h).
     */
    public double avgSpeed;
    
    /**
     * Average heading (°).
     */
    public double avgHeading;
    
    /**
     * Length of the track at this point (m).
     */
    public double lengthHere;
    
    /**
     * Duration of the track at this point (s).
     */
    public double durationHere;
    
    /**
     * Total upwards displacement (m).
     */
    public double upwardsHere;
    
    /**
     * Total downwards displacement (m).
     */
    public double downwardsHere;
    
    /** Creates a new instance of TrackPoint */
    public TrackPoint() {
    }
    
    /**
     * Formats this track point in a buffer so that it can be
     * written to the log.
     * Values are formatted in order to be readable as csv values.
     * @param buff buffer to write in.
     * @return Length of the formatted values in the buffer.
     */
    public int formatInBuffer(byte[] buff) {
        int cur=0;
        // Write latitude
        cur=Converters.writeDblInBuffer(buff, cur, 9, 6, this.lat);
        buff[cur]=','; cur++;
        // Write longitude
        cur=Converters.writeDblInBuffer(buff, cur, 10, 6, this.lon);
        buff[cur]=','; cur++;
        // Write altitude
        cur=Converters.writeDblInBuffer(buff, cur, 7, 1, this.altSeaLevel);
        buff[cur]=','; cur++;
        // Write UTM zone Id (lon+lat)
        cur=Converters.writeIntInBuffer(buff, cur, 2, this.uTMLonZone);
        buff[cur]=(byte) this.uTMLatZone; cur++;
        buff[cur]=','; cur++;
        // Write UTM easting
        cur=Converters.writeDblInBuffer(buff, cur, 9, 2, this.uTMEasting);
        buff[cur]=','; cur++;
        // Write UTM northing
        cur=Converters.writeDblInBuffer(buff, cur, 10, 2, this.uTMNorthing);
        buff[cur]=','; cur++;
        // Write date
        cur=Converters.writeIntInBuffer(buff, cur, 6, this.date);
        buff[cur]=','; cur++;
        // Write time
        cur=Converters.writeDblInBuffer(buff, cur, 10, 3, this.time);
        buff[cur]=','; cur++;
        // Write instantaneous speed
        cur=Converters.writeDblInBuffer(buff, cur, 5, 1, this.speed);
        buff[cur]=','; cur++;
        // Write instantaneous heading
        cur=Converters.writeDblInBuffer(buff, cur, 5, 1, this.heading);
        buff[cur]=','; cur++;
        // Write average speed
        cur=Converters.writeDblInBuffer(buff, cur, 5, 1, this.avgSpeed);
        buff[cur]=','; cur++;
        // Write average heading
        cur=Converters.writeDblInBuffer(buff, cur, 5, 1, this.avgHeading);
        buff[cur]=','; cur++;
        // Write total distance
        cur=Converters.writeDblInBuffer(buff, cur, 10, 1, this.lengthHere);
        buff[cur]=','; cur++;
        // Write total upwards
        cur=Converters.writeDblInBuffer(buff, cur, 7, 1, this.upwardsHere);
        buff[cur]=','; cur++;
        // Write total downwards
        cur=Converters.writeDblInBuffer(buff, cur, 7, 1, this.downwardsHere);
        buff[cur]=','; cur++;
        // Write total time
        int intTime = (int) this.durationHere;
        cur=Converters.writeIntInBuffer(buff, cur, 5, intTime);
        //buff[cur]=','; cur++;
        
        buff[cur]='\n'; cur++;
        return cur;
    }
        
    /**
     * Fill in attributes of this point from a string generated by the
     * <B>PositionTracer</B> log function.
     * @param logLine Input string to interpret.
     * @return true if the string looks correct, false otherwise.
     */
    public boolean readFromLogLine(String logLine) {
        double[] vDbl=new double[13];
        int[] vInt=new int[2];
        char[] vCh=new char[3];
        
        // Parse content
        String sequenceLogTrack="VVVCCCVVIVVVVVVVVI";
        try {
            Converters.parseCSVSentence(sequenceLogTrack, logLine.getBytes(),0,
                    logLine.length()-1, vDbl, vInt, vCh);
        } catch (NumberFormatException ex) {
            courselog.CourseLogAppForm.dbgL.addExceptionToLog(ex);
        }
        // Put values in fields
        this.lat=vDbl[0]; // Signed latitude
        this.lon=vDbl[1]; // Signed longitude
        if((time<=0.0d)||(lat>90.0d)||(lat<-90.0d)||(lon>180.0d)||(lon<-180.0d)) {
            return false;
        }
        this.altSeaLevel=vDbl[2]; // Altitude
        this.date=vInt[0]; // Date
        this.time=vDbl[5]; // Time UTC
        this.speed=vDbl[6];
        this.heading=vDbl[7];
        this.avgSpeed=vDbl[8];
        this.avgHeading=vDbl[9];
        this.lengthHere=vDbl[10];
        this.upwardsHere=vDbl[11];
        this.downwardsHere=vDbl[12];
        this.durationHere= (double) vInt[1];
        // Update computed values
        this.computeTime();
        this.computeLatLonToUTMRef();
        this.computeCartesian();
        
        return true;
    }
    
    public void copyFrom(Object param) {
        if(!(param instanceof MeasuredPoint)) {
            return;            
        }
        super.copyFrom(param);
        if(param instanceof TrackPoint) {
            TrackPoint tPt= (TrackPoint) param;
            durationHere= tPt.durationHere;
            lengthHere= tPt.lengthHere;
            avgHeading=tPt.avgHeading;
            avgSpeed=tPt.avgSpeed;
            upwardsHere=tPt.upwardsHere;
            downwardsHere=tPt.downwardsHere;
        }
    }
}
